﻿using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OneOfAll.Common.Models
{
    public class PeopleModel : BaseObjectModel
    {
        #region 基础属性
        private SexEnum sex = SexEnum.男;
        public SexEnum Sex
        {
            get { return sex; }
            set { sex = value; RaisePropertyChanged(); }
        }

        private string introduce = string.Empty;
        public string Introduce
        {
            get { return introduce; }
            set { introduce = value; RaisePropertyChanged(); }
        }

        private ObservableCollection<string> experiences = new ObservableCollection<string>();
        public ObservableCollection<string> Experiences
        {
            get { return experiences; }
            set { experiences = value; RaisePropertyChanged(); }
        }

        private int potential_Power = 0;
        public int Potential_Power
        {
            get { return potential_Power; }
            set { potential_Power = value; RaisePropertyChanged(); }
        }

        private int potential_Trick = 0;
        public int Potential_Trick
        {
            get { return potential_Trick; }
            set { potential_Trick = value; RaisePropertyChanged(); }
        }

        private int potential_Strong = 0;
        public int Potential_Strong
        {
            get { return potential_Strong; }
            set { potential_Strong = value; RaisePropertyChanged(); }
        }

        private int potential_Wit = 0;
        public int Potential_Wit
        {
            get { return potential_Wit; }
            set { potential_Wit = value; RaisePropertyChanged(); }
        }

        private int base_Power = 1;
        public int Base_Power
        {
            get { return base_Power; }
            set { base_Power = value; RaisePropertyChanged(); NeedExp_Power = (int)((Math.Pow((Base_Power - 1), 3) + 60) / 5 * (Math.Pow((Base_Power - 1), 2) + 60)); }
        }

        private int base_Trick = 1;
        public int Base_Trick
        {
            get { return base_Trick; }
            set { base_Trick = value; RaisePropertyChanged(); NeedExp_Trick = (int)((Math.Pow((Base_Trick - 1), 3) + 60) / 5 * (Math.Pow((Base_Trick - 1), 2) + 60)); }
        }

        private int base_Strong = 1;
        public int Base_Strong
        {
            get { return base_Strong; }
            set { base_Strong = value; RaisePropertyChanged(); MaxVitality = 100 + base_Strong * 20; NeedExp_Strong = (int)((Math.Pow((Base_Strong - 1), 3) + 60) / 5 * (Math.Pow((Base_Strong - 1), 2) + 60)); }
        }

        private int base_Wit = 1;
        public int Base_Wit
        {
            get { return base_Wit; }
            set { base_Wit = value; RaisePropertyChanged(); NeedExp_Wit = (int)((Math.Pow((Base_Wit - 1), 3) + 60) / 5 * (Math.Pow((Base_Wit - 1), 2) + 60)); }
        }

        private int exp_Power = 0;
        public int Exp_Power
        {
            get { return exp_Power; }
            set 
            { 
                exp_Power = value; 
                RaisePropertyChanged();
                while (Exp_Power >= NeedExp_Power)
                {
                    Exp_Power -= NeedExp_Power;
                    Base_Power++;
                }
            }
        }

        private int exp_Trick = 0;
        public int Exp_Trick
        {
            get { return exp_Trick; }
            set 
            { 
                exp_Trick = value; 
                RaisePropertyChanged();
                while (Exp_Trick >= NeedExp_Trick)
                {
                    Exp_Trick -= NeedExp_Trick;
                    Base_Trick++;
                }
            }
        }

        private int exp_Strong = 0;
        public int Exp_Strong
        {
            get { return exp_Strong; }
            set 
            { 
                exp_Strong = value; 
                RaisePropertyChanged();
                while (Exp_Strong >= NeedExp_Strong)
                {
                    Exp_Strong -= NeedExp_Strong;
                    Base_Strong++;
                }
            }
        }

        private int exp_Wit = 0;
        public int Exp_Wit
        {
            get { return exp_Wit; }
            set 
            { 
                exp_Wit = value; 
                RaisePropertyChanged();
                while (Exp_Wit >= NeedExp_Wit)
                {
                    Exp_Wit -= NeedExp_Wit;
                    Base_Wit++;
                }
            }
        }

        private int needExp_Power = 60;
        public int NeedExp_Power
        {
            get { return needExp_Power; }
            set { needExp_Power = value; RaisePropertyChanged(); }
        }

        private int needExp_Trick = 60;
        public int NeedExp_Trick
        {
            get { return needExp_Trick; }
            set { needExp_Trick = value; RaisePropertyChanged(); }
        }

        private int needExp_Strong = 60;
        public int NeedExp_Strong
        {
            get { return needExp_Strong; }
            set { needExp_Strong = value; RaisePropertyChanged(); }
        }

        private int needExp_Wit = 60;
        public int NeedExp_Wit
        {
            get { return needExp_Wit; }
            set { needExp_Wit = value; RaisePropertyChanged(); }
        }
        #endregion

        #region 战斗属性
        private ObservableCollection<EquipmentModel> equipmentList = new ObservableCollection<EquipmentModel>();
        public ObservableCollection<EquipmentModel> EquipmentList
        {
            get { return equipmentList; }
            set {  equipmentList = value; RaisePropertyChanged();}
        }


        private CareerModel career_Battle = null;
        public CareerModel Career_Battle
        {
            get { return career_Battle; }
            set 
            { 
                if (career_Battle != value) 
                    BattleCareerChanged(career_Battle); 
                career_Battle = value;  
                RaisePropertyChanged(); 
            }
        }


        private int lv_Battle = 1;
        public int Lv_Battle
        {
            get { return lv_Battle; }
            set
            {
                lv_Battle = value;
                RaisePropertyChanged();
                NeedExp_Battle = (int)((Math.Pow((Lv_Battle - 1), 3) + 60) / 5 * (Math.Pow((Lv_Battle - 1), 2) + 60));
            }
        }

        private int exp_Battle = 0;
        public int Exp_Battle
        {
            get { return exp_Battle; }
            set
            {
                exp_Battle = value;
                RaisePropertyChanged();
                while (Exp_Battle >= NeedExp_Battle && Lv_Battle < Career_Battle.Lv_Max)
                {
                    Exp_Battle -= NeedExp_Battle;
                    Lv_Battle++;
                }
            }
        }

        private int needExp_Battle = 60;
        public int NeedExp_Battle
        {
            get { return needExp_Battle; }
            set { needExp_Battle = value; RaisePropertyChanged(); }
        }

        private int power = 0;
        public int Power
        {
            get { return power; }
            set { power = value; RefushBattleProperty(); RaisePropertyChanged(); }
        }

        private int trick = 0;
        public int Trick
        {
            get { return trick; }
            set { trick = value; RefushBattleProperty(); RaisePropertyChanged(); }
        }

        private int strong = 0;
        public int Strong
        {
            get { return strong; }
            set { strong = value; RefushBattleProperty(); RaisePropertyChanged(); }
        }

        private int wit = 0;
        public int Wit
        {
            get { return wit; }
            set { wit = value; RefushBattleProperty();RaisePropertyChanged(); }
        }

        private int all_Power = 0;
        public int All_Power
        {
            get { return all_Power; }
            set { all_Power = value; RaisePropertyChanged(); }
        }

        private int all_Trick = 0;
        public int All_Trick
        {
            get { return all_Trick; }
            set { all_Trick = value; RaisePropertyChanged(); }
        }

        private int all_Strong = 0;
        public int All_Strong
        {
            get { return all_Strong; }
            set { all_Strong = value; RaisePropertyChanged(); }
        }

        private int all_Wit = 0;
        public int All_Wit
        {
            get { return all_Wit; }
            set { all_Wit = value; RaisePropertyChanged(); }
        }

        private int hp = 0;
        public int Hp
        {
            get { return hp; }
            set { hp = value; RaisePropertyChanged(); }
        }

        private int maxHp = 0;
        public int MaxHp
        {
            get { return maxHp; }
            set { maxHp = value; RaisePropertyChanged(); }
        }

        private int mp = 0;
        public int Mp
        {
            get { return mp; }
            set { mp = value; RaisePropertyChanged(); }
        }

        private int maxMp = 0;
        public int MaxMp
        {
            get { return maxMp; }
            set { maxMp = value; RaisePropertyChanged(); }
        }

        private int attack = 0;
        public int Attack
        {
            get { return attack; }
            set { attack = value; RaisePropertyChanged(); }
        }

        private int defense = 0;
        public int Defense
        {
            get { return defense; }
            set { defense = value; RaisePropertyChanged(); }
        }

        private int dodge = 0;
        public int Dodge
        {
            get { return dodge; }
            set {  dodge = value; RaisePropertyChanged();}
        }

        private int accurate = 0;
        public int Accurate
        {
            get { return accurate; }
            set { accurate = value; RaisePropertyChanged(); }
        }

        private int criticalChance = 5;
        public int CriticalChance
        {
            get { return criticalChance; }
            set { criticalChance = value; RaisePropertyChanged(); }
        }

        private int criticalValue = 150;
        public int CriticalValue
        {
            get { return criticalValue; }
            set { criticalValue = value; RaisePropertyChanged(); }
        }

        private double attackSpeed = 1;
        public double AttackSpeed
        {
            get { return attackSpeed; }
            set { attackSpeed = value; RaisePropertyChanged(); }
        }

        private double attackInterval = 2;
        public double AttackInterval
        {
            get { return attackInterval; }
            set { attackInterval = value; RaisePropertyChanged(); }
        }

        private int potentialLength = 3;
        public int PotentialLength
        {
            get { return potentialLength; }
            set { potentialLength = value; RaisePropertyChanged(); }
        }

        private int careerMaster_Power = 0;
        /// <summary>
        /// 职业精通力道
        /// </summary>
        public int CareerMaster_Power
        {
            get { return careerMaster_Power; }
            set { careerMaster_Power = value; RaisePropertyChanged(); }
        }

        private int careerMaster_Trick = 0;
        public int CareerMaster_Trick
        {
            get { return careerMaster_Trick; }
            set { careerMaster_Trick = value; RaisePropertyChanged(); }
        }

        private int careerMaster_Strong = 0;
        public int CareerMaster_Strong
        {
            get { return careerMaster_Strong; }
            set { careerMaster_Strong = value; RaisePropertyChanged(); }
        }

        private int careerMaster_Wit = 0;
        public int CareerMaster_Wit
        {
            get { return careerMaster_Wit; }
            set { careerMaster_Wit = value; RaisePropertyChanged(); }
        }
        #endregion

        #region 生活属性
        private CareerModel career_Live = null;
        public CareerModel Career_Live
        {
            get { return career_Live; }
            set { career_Live = value; RaisePropertyChanged(); }
        }

        private int lv_Live = 1;
        public int Lv_Live
        {
            get { return lv_Live; }
            set
            {
                lv_Live = value;
                RaisePropertyChanged();
                NeedExp_Battle = (int)((Math.Pow((Lv_Live - 1), 3) + 60) / 5 * (Math.Pow((Lv_Live - 1), 2) + 60));
            }
        }

        private int exp_Live = 0;
        public int Exp_Live
        {
            get { return exp_Live; }
            set
            {
                exp_Live = value;
                RaisePropertyChanged();
                while (Exp_Live >= NeedExp_Live && Lv_Live < Career_Live.Lv_Max)
                {
                    Exp_Live -= NeedExp_Live;
                    Lv_Live++;
                }
            }
        }

        private int needExp_Live = 60;
        public int NeedExp_Live
        {
            get { return needExp_Live; }
            set { needExp_Live = value; RaisePropertyChanged(); }
        }

        private int homeX = -1;
        public int HomeX
        {
            get { return homeX; }
            set { homeX = value; RaisePropertyChanged(); }
        }

        private int homeY = -1;
        public int HomeY
        {
            get { return homeY; }
            set { homeY = value; RaisePropertyChanged(); }
        }

        private int homeKey = -1;
        public int HomeKey
        {
            get { return homeKey; }
            set { homeKey = value; RaisePropertyChanged(); }
        }

        private int targetKey = -1;
        public int TargetKey
        {
            get { return targetKey; }
            set { targetKey = value; RaisePropertyChanged(); }
        }

        private int workKey = -1;
        public int WorkKey
        {
            get { return workKey; }
            set { workKey = value; RaisePropertyChanged(); }
        }

        private int mood = 100;
        /// <summary>
        /// 心情
        /// </summary>
        public int Mood
        {
            get { return mood; }
            set { mood = value; RaisePropertyChanged(); }
        }

        private double vitality = 100.0;
        /// <summary>
        /// 当前精力
        /// </summary>
        public double Vitality
        {
            get { return vitality; }
            set { vitality = value; RaisePropertyChanged(); }
        }

        private double maxVitality = 100.0;
        /// <summary>
        /// 最大精力
        /// </summary>
        public double MaxVitality
        {
            get { return maxVitality; }
            set { maxVitality = value; RaisePropertyChanged(); }
        }

        private int master_Money = 10;
        public int Master_Money
        {
            get { return master_Money; }
            set {  master_Money = value; RaisePropertyChanged();}
        }

        private int master_Food = 10;
        public int Master_Food
        {
            get { return master_Food; }
            set { master_Food = value; RaisePropertyChanged(); }
        }

        private int master_Wood = 10;
        public int Master_Wood
        {
            get { return master_Wood; }
            set { master_Wood = value; RaisePropertyChanged(); }
        }

        private int master_Mineral = 10;
        public int Master_Mineral
        {
            get { return master_Mineral; }
            set { master_Mineral = value; RaisePropertyChanged(); }
        }

        private int master_Fabric = 10;
        public int Master_Fabric
        {
            get { return master_Fabric; }
            set { master_Fabric = value; RaisePropertyChanged(); }
        }

        private int master_Gem = 10;
        public int Master_Gem
        {
            get { return master_Gem; }
            set { master_Gem = value; RaisePropertyChanged(); }
        }

        private bool enabled_Production = true;
        public bool Enabled_Production
        {
            get { return enabled_Production; }
            set
            {
                enabled_Production = value;
                if (Global.GlobalResource != null)
                    Messenger.Default.Send(this, Global.GlobalResource.CityWalkParamsChanged);
                RaisePropertyChanged();
            }
        }

        private bool enabled_Train = true;
        public bool Enabled_Train
        {
            get { return enabled_Train; }
            set
            {
                enabled_Train = value;
                if (Global.GlobalResource != null)
                    Messenger.Default.Send(this, Global.GlobalResource.CityWalkParamsChanged);
                RaisePropertyChanged();
            }
        }

        private bool enabled_Make = true;
        public bool Enabled_Make
        {
            get { return enabled_Make; }
            set
            {
                enabled_Make = value;
                if (Global.GlobalResource != null)
                    Messenger.Default.Send(this, Global.GlobalResource.CityWalkParamsChanged);
                RaisePropertyChanged();
            }
        }

        private int cityWalkRange = 50;
        public int CityWalkRange
        {
            get { return cityWalkRange; }
            set
            {
                cityWalkRange = value;
                if (Global.GlobalResource != null)
                    Messenger.Default.Send(this, Global.GlobalResource.CityWalkParamsChanged);
                RaisePropertyChanged();
            }
        }

        private ObservableCollection<ConstructionPathModel> cityWalkPathList = new ObservableCollection<ConstructionPathModel>();
        public ObservableCollection<ConstructionPathModel> CityWalkPathList
        {
            get { return cityWalkPathList; }
            set { cityWalkPathList = value; RaisePropertyChanged(); }
        }
        #endregion

        private bool isGoOut = false;
        public bool IsGoOut
        {
            get { return isGoOut; }
            set { isGoOut = value; RaisePropertyChanged(); }
        }

        private MonsterModel attachMonster = null;
        public MonsterModel AttachMonster
        {
            get { return attachMonster; }
            set { attachMonster = value; RaisePropertyChanged(); }
        }

        public PeopleModel()
        {
            EquipmentList.CollectionChanged += EquipmentList_CollectionChanged;
        }

        private void EquipmentList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            RefushBattleProperty();
        }

        public int GetProductEffect(MaterialsTypeEnum type)
        {
            switch (type)
            {
                case MaterialsTypeEnum.金钱:
                    return Master_Money;
                case MaterialsTypeEnum.粮草:
                    return Master_Food;
                case MaterialsTypeEnum.木材:
                    return Master_Wood;
                case MaterialsTypeEnum.石材:
                case MaterialsTypeEnum.铁:
                case MaterialsTypeEnum.铜:
                    return Master_Mineral;
                case MaterialsTypeEnum.布:
                case MaterialsTypeEnum.丝绸:
                    return Master_Fabric;
                case MaterialsTypeEnum.宝石:
                    return Master_Gem;
                default:
                    return 10;
            }
        }

        private void BattleCareerChanged(CareerModel oldCareer)
        {
            if (Lv_Battle >= oldCareer.Lv_Max)
            {
                CareerMaster_Power += oldCareer.Master_Power;
                CareerMaster_Strong += oldCareer.Master_Power;
                CareerMaster_Trick += oldCareer.Master_Power;
                CareerMaster_Wit += oldCareer.Master_Power;
                Power += oldCareer.Master_Power;
                Strong += oldCareer.Master_Strong;
                Trick += oldCareer.Master_Trick;
                Wit += oldCareer.Master_Wit;
            }
            Power -= ((Lv_Battle - 1) * oldCareer.GroupUp_Power);
            Strong -= ((Lv_Battle - 1) * oldCareer.GroupUp_Strong);
            Trick -= ((Lv_Battle - 1) * oldCareer.GroupUp_Trick);
            Wit -= ((Lv_Battle - 1) * oldCareer.GroupUp_Wit);
            Lv_Battle = 1;
            Exp_Battle = 0;
            PotentialLength = Career_Battle.PotentialLength;
            AttackInterval = Career_Battle.AttackInterval;
            AttackSpeed = Career_Battle.AttackSpeed;
        }

        private void RefushBattleProperty()
        {
            All_Power = Power + GetPropertyByEquipment(0);
            All_Power = All_Power > 0 ? All_Power : 0;
            All_Strong = Strong + GetPropertyByEquipment(1);
            All_Strong = All_Strong > 0 ? All_Strong : 0;
            All_Trick = Trick + GetPropertyByEquipment(2);
            All_Trick = All_Trick > 0 ? All_Trick : 0;
            All_Wit = Wit + GetPropertyByEquipment(3);
            All_Wit = All_Power > 0 ? All_Wit : 0;
            MaxHp = (int)(Math.Sqrt(Base_Strong) * 20 * All_Strong + GetPropertyByEquipment(4)) + 100;
            if (Hp > MaxHp) Hp = MaxHp;
            MaxMp = (int)(Math.Sqrt(Base_Wit) * 5 * All_Wit + GetPropertyByEquipment(5)) + 30;
            if (Mp > MaxMp) Mp = MaxMp;
            Attack = (int)(Math.Sqrt(Base_Power) * 3 * All_Power + GetPropertyByEquipment(6));
            Defense = (int)(Math.Sqrt(Base_Strong) * 0.2 * All_Strong + GetPropertyByEquipment(7));
            Dodge = (int)(Math.Sqrt(Base_Trick) * 1 * All_Trick + GetPropertyByEquipment(9));
            Accurate = (int)(Math.Sqrt(Base_Trick) * 1 * All_Trick + GetPropertyByEquipment(10));
            CriticalChance = Career_Battle.CriticalChance + GetPropertyByEquipment(11);
            CriticalValue = Career_Battle.CriticalValue + GetPropertyByEquipment(12);
        }

        /// <summary>
        /// 获取装备属性 0-力道 1-强壮 2-灵巧 3-悟性 4-HP 5-MP 6-攻击 7-防御 8-闪避 9-命中 10-暴击率 11-暴击伤害
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private int GetPropertyByEquipment(int type)
        {
            switch (type)
            {
                case 0:
                    return EquipmentList.Sum(t => t.Power);
                case 1:
                    return EquipmentList.Sum(t => t.Strong);
                case 2:
                    return EquipmentList.Sum(t => t.Trick);
                case 3:
                    return EquipmentList.Sum(t => t.Wit);
                case 4:
                    return EquipmentList.Sum(t => t.Hp);
                case 5:
                    return EquipmentList.Sum(t => t.Mp);
                case 6:
                    return EquipmentList.Sum(t => t.Attack);
                case 7:
                    return EquipmentList.Sum(t => t.Defense);
                case 8:
                    return EquipmentList.Sum(t => t.Dodge);
                case 9:
                    return EquipmentList.Sum(t => t.Accurate);
                case 10:
                    return EquipmentList.Sum(t => t.CriticalChance);
                case 11:
                    return EquipmentList.Sum(t => t.CriticalValue);
                default:
                    return 0;
            }
        }
    }


    public class PeopleWorkInfoModel : BaseModel
    {
        private string name = string.Empty;
        public string Name
        {
            get { return name; }
            set { name = value; RaisePropertyChanged(); }
        }

        private double schedule = 0.0;
        public double Schedule
        {
            get { return schedule; }
            set { schedule = value; RaisePropertyChanged(); }
        }

        private double workSpeed = 10.0;
        public double WorkSpeed
        {
            get { return workSpeed; }
            set { workSpeed = value; RaisePropertyChanged(); }
        }

        private double maxValue = 100.0;
        public double MaxValue
        {
            get { return maxValue; }
            set { maxValue = value; RaisePropertyChanged(); }
        }
    }
}
